package people;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import permission.RoleManager;
import permission.Roleable;
import permission.Secureable;
import permission.role.Role;

public class Person implements Roleable, Secureable {

	private final Set<Role> roles = new HashSet<Role>();
	private List<Role> allowedRoles = new ArrayList<Role>();
	
	protected final RoleManager rm = RoleManager.INSTANCE;
	
	private String uniqueIdentifier;
	private Name name;
	
	public Person(Name name) {
		uniqueIdentifier = UUID.randomUUID().toString();
		this.name = name;
	}
	
	public String getUniqueIdentifier() {
		return uniqueIdentifier;
	}
	
	void setName(Name name) {
		this.name = name;
	}
	
	public Name getName(Roleable role) {
		boolean granted = rm.isAccessGranted(this, role);
		
		return granted ? name : null;
	}
	
	@Override
	public Collection<Role> getRoles() {
		return roles;
	}
	
	@Override
	public void addRole(Role role) {
		roles.add(role);
	}
	
	public void removeRole(Role role) {
		roles.remove(role);
	}
	
	public static class Name {
		private String firstName;
		private String lastName;
		
		public Name(String firstName, String lastName) {
			this.firstName = firstName;
			this.lastName = lastName;
		}
		
		public String getFullName() {
			return firstName + " " + lastName;
		}
		
		public String getFirstName() {
			return firstName;
		}
		public void setFirstName(String firstName) {
			this.firstName = firstName;
		}
		public String getLastName() {
			return lastName;
		}
		public void setLastName(String lastName) {
			this.lastName = lastName;
		}
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime
				* result
				+ ((uniqueIdentifier == null) ? 0 : uniqueIdentifier.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		Person other = (Person) obj;
		if (uniqueIdentifier == null) {
			if (other.uniqueIdentifier != null) {
				return false;
			}
		} else if (!uniqueIdentifier.equals(other.uniqueIdentifier)) {
			return false;
		}
		return true;
	}

	@Override
	public Collection<Role> getAccessRoles() {
		return allowedRoles;
	}

	@Override
	public void addAccessRole(Role role) {
		if(role == null) {
			return;
		}
		allowedRoles.add(role);
	}
}
